package fr.chrysalis.ui
{
	import com.hydrotik.queueloader.QueueLoader;
	import com.hydrotik.queueloader.QueueLoaderEvent;
	
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.EventDispatcher;
	import flash.text.TextFormat;
	import flash.utils.Dictionary;
	
	import fr.chrysalis.ui.assets.SWFAsset;
	import fr.chrysalis.ui.components.core.Font;
	import fr.chrysalis.ui.components.core.Form;
	import fr.chrysalis.ui.components.core.Style;
	import fr.chrysalis.ui.events.UIEvent;
	import fr.chrysalis.utils.DLinkedList;
	import fr.chrysalis.utils.Debug;

	/**
	 * Library de composant
	 * Nécessite TweenMax et QueueLoader
	 * TweenMax 11.37 : http://www.greensock.com/tweenmax/
	 * QueueLoader 3.1.8 : https://github.com/hydrotik/QueueLoader/wiki/
	 */
	public class UI extends EventDispatcher
	{
		
		/**
		 * Contient le stage référent
		 */
		public var stage:Stage;
		
		/**
		 * Contient la liste des assets 
		 */
		public var library:Dictionary;
		
		/**
		 * Contient la liste des formulaires
		 */
		public var forms:DLinkedList;
		
		/**
		 * Génération d'id pour les composants
		 */
		private var idComponent:int;
		
		/**
		 * Loader 
		 */
		private var qloader:QueueLoader;
		
		/**
		 * Récupère la valeur de debugage 
		 * @return true ou false
		 */
		public static function get debug():Boolean
		{
			return UIConstants.DEBUG;
		}
		
		/**
		 * Définit la valeur de débugoge (par default false) 
		 * @param value nouvelle valeur
		 */
		public static function set debug(value:Boolean):void
		{
			UIConstants.DEBUG = value;
		}
		
		private static var _instance:UI;
		
		/**
		 * Singleton 
		 * @return 
		 */
		public static function getInstance():UI {
			if ( _instance == null ) _instance = new UI();
			return _instance as UI;
		}
		
		public function UI()
		{
			this.library = new Dictionary();
			this.forms = new DLinkedList();
			this.idComponent = 0;
			
			this.initQueueLoader();
			
			var defaultFormat:TextFormat = new TextFormat();
			defaultFormat.font = null;
			defaultFormat.bold = true;
			defaultFormat.size = 12;
			defaultFormat.color = 0x000000;
			
			new Style('default', defaultFormat);
		}
		
		/**
		 * Initialisation de la queueloader 
		 */
		private function initQueueLoader():void {
			this.qloader = new QueueLoader(true);
			this.qloader.addEventListener( QueueLoaderEvent.ITEM_START, onItemStart, false, 0, true );
			this.qloader.addEventListener( QueueLoaderEvent.ITEM_ERROR, onItemError, false, 0, true );
			this.qloader.addEventListener( QueueLoaderEvent.ITEM_COMPLETE, onItemLoaded, false, 0, true );
			this.qloader.addEventListener( QueueLoaderEvent.QUEUE_PROGRESS, onQueueProgress, false, 0, true );
			this.qloader.addEventListener( QueueLoaderEvent.QUEUE_COMPLETE, onQueueComplete, false, 0, true );
		}
		
		/**
		 * Ajoute un item à charger
		 * @param path Chemin de l'item
		 * @param name Nom de l'item
		 * @param type Type de l'item (UIType)
		 */
		public function add(path:String, name:String, type:String = UIType.COMPONENT):void
		{
			UI.getInstance().qloader.addItem( path , null, {title: type, dataName: name});
		}
		
		/**
		 * Début du chargement 
		 */
		public function load():void
		{
			if(UI.debug){
				Debug.dump("");
				Debug.dump("--------------------------------------");
				Debug.dump("######### Chargement de l'UI #########");
			}
			UI.getInstance().qloader.execute();
		}
		
		/**
		 * Handler lorsqu'un item commence à etre chargé
		 */
		private function onItemStart(evt:QueueLoaderEvent):void
		{
			if(UI.debug){
				Debug.dump('Début du chargement de : ' + evt.path.url);
			}
			this.dispatchEvent(new UIEvent(UIEvent.ITEM_START, evt));
		}
		
		/**
		 * Handler lorsqu'un item a échoué
		 */
		private function onItemError(evt:QueueLoaderEvent):void
		{
			if(UI.debug){
				Debug.dump(evt.message);
			}
			this.dispatchEvent(new UIEvent(UIEvent.ITEM_ERROR, evt));
			
		}
		
		/**
		 * Handler lorsqu'un item est loaded
		 */
		private function onItemLoaded(evt:QueueLoaderEvent):void
		{
			
			if(UI.debug){
				Debug.dump('Chargement effectué : ' + evt.path.url);
			}
			
			var loaderClass:Class = evt.targ.contentLoaderInfo.applicationDomain.getDefinition('component') as Class;

			this.library[evt.info.dataName] = loaderClass;
			
			switch(evt.title) {
				case UIType.FONT:
					var font:Font = new Font(new SWFAsset(loaderClass));
					break;
			}
			
		}
		
		/**
		 * Handler lors du chargement
		 */ 
		private function onQueueProgress(evt:QueueLoaderEvent):void
		{
			this.dispatchEvent(new UIEvent(UIEvent.PROGRESS, evt));
		}
		
		/**
		 * Handler lors de la fin du loading
		 */
		private function onQueueComplete(evt:QueueLoaderEvent):void
		{
			if(UI.debug){
				Debug.dump("######### Fin de chargement de l'UI #########");
				Debug.dump("---------------------------------------------");
				Debug.dump("");
			}
			
			this.initQueueLoader();
			
			this.dispatchEvent(new UIEvent(UIEvent.COMPLETE, evt));
			
		}
		
		/**
		 * Récupération d'un asset 
		 * @param name Nom de l'asset à récupérer
		 * @return Asset choisi
		 */
		public static function get(name:String):Class
		{
			if(UI.getInstance().library[name] != undefined){
				return UI.getInstance().library[name];
			}
			return null;
		}
		
		/**
		 * Ajoute un formulaire dans la liste 
		 * @param form formulaire à ajouter
		 */
		public function addForm(form:Form):void {
			this.forms.push(form);
		}
		
		/**
		 * Supprime un formulaire dans la liste 
		 * @param form formulaire à supprimer
		 */
		public function removeForm(form:Form):void {
			this.forms.remove(form);
		}
		
		/**
		 * Génère un id pour les composants
		 */
		public function getIdComponent():int {
			return this.idComponent++;
		}
		
		/**
		 * Dump la list des assets
		 */
		public static function dumpLibrary():void {
			Debug.dump("Assets présent d'ans l'UI");
			Debug.dump(UI.getInstance().library);
			Debug.dump("");
		}
		
	}
}